package cn.ac.siom.query.common;

import clover.org.apache.commons.lang.SystemUtils;
import cn.ac.siom.query.dao.ITab_ThesisDao;
import cn.ac.siom.query.dao.WordCountDao;
import cn.ac.siom.query.util.StringUtil;
import cn.ac.siom.query.vo.Tab_Thesis;
import cn.ac.siom.query.vo.WordCount;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Date;
import java.util.List;

@Component
public class WordCountTask {
    public static final Logger LOGGER = LoggerFactory.getLogger(WordCountTask.class);

    @Resource
    private WordCountDao wordCountDao;

    @Resource
    private ITab_ThesisDao tab_thesisDao;

    public static int status;

    public static int TASK_INIT = 0;

    public static int TASK_RUNNING = 1;

    public static int TASK_FINISHED = 2;

    public static int TASK_ERROR = 3;

    @PostConstruct
    public void init() {
        status = TASK_INIT;
    }

    @Async
    public void excute() {
        try {
            status = TASK_RUNNING;

            Date date = new Date();

            // prepare file
            String path = StringUtil.getXmlPath();
            File wordFile = new File(path + File.separator + "wordCount" + File.separator + "data.csv");
            if (!wordFile.exists()) {
                wordFile.createNewFile();
            }
            FileWriter fileWriter = new FileWriter(wordFile);
            fileWriter.write("");

            // query tab_thesis and write to file
            List<Tab_Thesis> tab_thesisList = tab_thesisDao.selectWordCount();
            for (Tab_Thesis tab_thesis : tab_thesisList) {
                fileWriter.append(tab_thesis.getField17() + "," + tab_thesis.getField18() + "," + tab_thesis.getField28() + "," + tab_thesis.getField29() + "," + tab_thesis.getField30() + ","
                        + tab_thesis.getField31() + "," + tab_thesis.getField32() + "," + tab_thesis.getField33() + ",");
            }
            fileWriter.close();

            // exec
            String command = "";
            if (SystemUtils.IS_OS_LINUX) {
                command = "python3 " + path + "wordCount" + File.separator + "wordcount2.py";
            } else {
                command = "python " + path + "wordCount" + File.separator + "wordcount2.py";
            }

            System.out.println("command : " + command);
            Process process = Runtime.getRuntime().exec(command);
            InputStreamReader ir = new InputStreamReader(process.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);
            String result = input.readLine();
            System.out.println("result : " + result);

            // delete record
            wordCountDao.deleteAll();

            // resolve
            result = result.replace("[", "");
            result = result.replace("]", "");
            String[] tmpArr = result.split("\\$\\$\\$\\$");
            for (String wordAndCount : tmpArr) {
                // wordAndCount format is (('error', 'rate'), 677)
                String countStr = wordAndCount.substring(wordAndCount.indexOf("), ") + 3, wordAndCount.length() - 2);
                Integer count = 0;
                String name = "";
                try {
                    count = Integer.valueOf(countStr);
                } catch (Exception e) {
                    LOGGER.error("parse count of {} failed, count = {}", wordAndCount, countStr, e);
                }
                String tmpStr = wordAndCount.substring(0, wordAndCount.indexOf("), "));
                String[] tmp2 = tmpStr.split("', '");
                for (String tmp3 : tmp2) {
                    tmp3 = tmp3.replace(",", "");
                    tmp3 = tmp3.replace("'", "");
                    tmp3 = tmp3.replace("(", "");
                    tmp3 = tmp3.replace(")", "");
                    name += tmp3.trim() + " ";
                }
                name = name.substring(0, name.length() - 1);
                WordCount wordCount = new WordCount(name, count, date);
                wordCountDao.insert(wordCount);
            }

            input.close();
            ir.close();
            status = TASK_FINISHED;
        } catch (Exception e) {
            LOGGER.error("excute WordCountTask failed, exception : ", e);
            status = TASK_ERROR;
        }
    }

    public static int getStatus() {
        return status;
    }

    public static void setStatus(int status) {
        WordCountTask.status = status;
    }

}
